#include <SFML/Graphics/RenderWindow.hpp>
#include <nice2d/macros.h>
#include <nice2d/background.h>
#include <nice2d/imagedescriptor.h>
#include <nice2d/util.h>
#include <nice2d/animation.h>
#include <nice2d/tilemap.h>
#include <nice2d/widgets/helplistener.h>
#include <nice2d/components/imagemanager.h>
#include <nice2d/actions/sequenceaction.h>
#include <nice2d/piece/piecescene.h>
#include <nice2d/piece/actions/fightanimationaction.h>
#include <nice2d/actions/colorizedaction.h>

#define SCENE_WIDTH  900.0f
#define SCENE_HEIGHT 680.0f

class UnitScene : public PieceScene
{
public:
    void onInitialed()override
    {
        setSceneBox({0.0f, 0.0f, SCENE_WIDTH, SCENE_HEIGHT});
        setBackground(Background::create("./../data/images/ground3.png", true));

        initTileMap();

        deployPieces();
        initControls();

        std::shared_ptr<ImageDescriptor> imageDescriptor= std::make_shared<ImageDescriptor>();
        imageDescriptor->file = "./../data/animation/flare.png";
        imageDescriptor->imageSize = {128,128};

        for(int i=0;i<6;i++)
        {
            imageDescriptor->areas.push_back({i*128,0,128,128});
        }

        fightAnimation = std::make_shared<Animation>();
        fightAnimation->setBackgroundColor(sf::Color::Transparent);
        fightAnimation->setDurationPerFrame(0.2f);
        fightAnimation->setImageDescriptor(imageDescriptor);
    }
private:
    void initTileMap()
    {
        tileMap = TileMap::create(TileMapType::TileMapType_Hex);
        tileMap->init(13,9,96);

        tileMap->accept([](int32_t x, int32_t y, std::shared_ptr<Tile> tile)
        {
            tile->setOutlineColor(sf::Color(128,128,128));
            tile->setOutlineThickness(0.5f);
            tile->setWalkable(true);
        });

        addChild(tileMap);
        setTileMap(tileMap);
        tileMap->tileClicked.connect(std::bind(&UnitScene::tileClicked,this,std::placeholders::_1,std::placeholders::_2));
    }

    void deployPieces()
    {
        TextOption opt;
        opt.characterSize = 15;

        sf::Color spriteColor[] = {sf::Color::Red,sf::Color::Green};

        for(int i=0;i<12;i++)
        {
            auto piece = std::make_shared<Piece>(opt);
            piece->setName(std::wstring(L"Piece") + std::to_wstring(i+1));
            piece->setHitPoint(rand()%5+1);
            piece->setAttack(rand()%5+1);
            piece->setDefense(rand()%5+1);
            piece->setMovement(rand()%5+1);
            piece->setBackgroundColor(sf::Color(140,140,140));
            piece->setSpriteColor(spriteColor[i%2]);
            piece->setSize(64,64);
            piece->addPieceIcon("./../data/icon/nato/units/infantry.png");
            piece->addPieceIcon("./../data/icon/nato/sizes/group.png");
            piece->setTextColor(sf::Color::White);
            addPiece(piece,rand()%13,rand()%9);
        }
    }

    void tileClicked(int32_t x,int32_t y)
    {
        if(currentPiece)
            return;

        auto tile = tileMap->getTileByIndex(x,y);
        auto sprite = tile->getSprite();
        if(sprite)
        {
            currentPiece = std::dynamic_pointer_cast<Piece>(sprite);

            auto actions = std::make_shared<SequenceAction>();
            actions->stoped.connect(std::bind(&UnitScene::actionStoped,this));
            actions->setOwner(currentPiece);

            auto fight = std::make_shared<FightAnimationAction>(as<Scene>(),tile->getPosition(),0.5f);
            fight->setAnimation(fightAnimation);
            fight->setOwner(sprite);
            actions->addAction(fight);

            auto colorized = std::make_shared<ColorizedAction>(sf::Color(100,100,100),0.5f);
            actions->addAction(colorized);
            runAction(actions);
        }
    }

    void actionStoped()
    {
        if(currentPiece)
        {
            removePiece(currentPiece);
            currentPiece.reset();
        }
    }

    void initControls()
    {
        auto helper = std::make_shared<HelpListener>(L"fight animation");
        registerMessageListener(helper);
    }
private:
    std::shared_ptr<TileMap> tileMap;
    std::shared_ptr<Piece> currentPiece;

    std::shared_ptr<Animation> fightAnimation;
};

DECLARE_MAIN_FUNCTION_WITH_SCENE(SCENE_WIDTH, SCENE_HEIGHT, "unit22", UnitScene)
